package com.one.group.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.one.group.admin.mapper.OwnerMapper;
import com.one.group.admin.mapper.SpHouseMapper;
import com.one.group.enums.ErrorCode;
import com.one.group.exception.BusinessException;
import com.one.group.model.dto.AddOwnerAccountNumberDto;
import com.one.group.model.dto.OwnerAddDto;
import com.one.group.model.dto.OwnerQueryDto;
import com.one.group.model.dto.OwnerSearchVo;
import com.one.group.model.entity.Owner;
import com.one.group.model.entity.SpHouse;
import com.one.group.model.vo.OwnerListVo;
import com.one.group.model.vo.OwnerDetailVo;
import com.one.group.admin.excel.OwnerData;
import com.one.group.admin.excel.OwnerDataReadListener;
import com.one.group.service.OwnerService;
import com.one.group.service.SpHouseService;
import com.alibaba.excel.EasyExcel;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class OwnerServiceImpl extends ServiceImpl<OwnerMapper, Owner> implements OwnerService {

    @Autowired
    private OwnerMapper ownerMapper;
    @Autowired
    private SpHouseService spHouseService;
    @Autowired
    private SpHouseMapper spHouseMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOwner(OwnerAddDto ownerAddDto) {
        // 获取租户ID
        Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));
        Owner owner = new Owner();
        owner.setTenantId(tenantId);
        owner.setCellId(ownerAddDto.getCellId());
        owner.setName(ownerAddDto.getName());
        owner.setPhone(ownerAddDto.getPhone());
        owner.setGender(ownerAddDto.getGender());
        owner.setEmail(ownerAddDto.getEmail());
        owner.setRemark(ownerAddDto.getRemark());
        owner.setIdCard(ownerAddDto.getIdCard());
        owner.setMoveInTime(ownerAddDto.getMoveInTime());
        owner.setResidentType(ownerAddDto.getResidentType());
        owner.setStatus(0);

        try {
            int result = ownerMapper.addOwner(owner);
            if (result > 0) {
                // 获取生成的主键ID
                Long ownerId = owner.getId();
                //判断房屋id对应的业主ID为不为空
                Long isOwnerId = ownerMapper.getOwnerIdByHouseId(ownerAddDto.getHouseId());
                if (isOwnerId != null) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "该房屋已绑定其他业主!");
                }
                //根据房屋ID添加业主ID
                Boolean houseResult = spHouseService.addOwnerIdById(ownerAddDto.getHouseId(), ownerId);
                if(houseResult){
                    AddOwnerAccountNumberDto addOwnerAccountNumberDto = new AddOwnerAccountNumberDto();
                    addOwnerAccountNumberDto.setPhone(ownerAddDto.getPhone());
                    addOwnerAccountNumberDto.setName(ownerAddDto.getName());
                    addOwnerAccountNumberDto.setIdCard(ownerAddDto.getIdCard());
                    addOwnerAccountNumberDto.setGender(ownerAddDto.getGender());
                    addOwnerAccountNumberDto.setEmail(ownerAddDto.getEmail());
                    addOwnerAccountNumberDto.setCellId(ownerAddDto.getCellId());
                    addOwnerAccountNumberDto.setTenantId(tenantId);
                    rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                    rabbitTemplate.convertAndSend("gxa.direct","addOwnerAccountNumber",addOwnerAccountNumberDto);
                }
                return houseResult;
            } else {
                throw new BusinessException(ErrorCode.ADD_ERROR.getCode(), "添加业主失败!");
            }
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.ADD_ERROR.getCode(), "添加业主失败:"+e.getMessage());
        }
    }

    @Override
    public List<OwnerListVo> getOwnerList(OwnerQueryDto ownerQueryDto) {
        Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));
        ownerQueryDto.setTenantId(tenantId);
        try {
            return ownerMapper.findOwnerByQueryDto(ownerQueryDto);
        }catch (Exception e){
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "查询业主列表失败!");
        }

    }
    @Autowired
    public static final String CACHE_KEY_PREFIX_HOUSE = "cache:houseList:";
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean moveOutOwner(Long houseId) {
        try {
            if (houseId == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "房屋ID不能为空，请联系管理员删除！");
            }

            // 1. 先获取房屋对应的业主ID
            Long ownerId = ownerMapper.getOwnerIdByHouseId(houseId);
            if (ownerId == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "该房屋没有绑定业主!");
            }
            
            // 2. 更新房屋表，将业主ID设为NULL
            boolean houseResult = ownerMapper.moveOutOwner(houseId);
            if (!houseResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "更新房屋信息失败!");
            }
            List<Long> ownerIds = new ArrayList<>();
            ownerIds.add(ownerId);
            List<Integer> currentStatuses = ownerMapper.getOwnerStatusByIds(ownerIds);
            Integer currentStatus = currentStatuses.get(0);
            if(currentStatus != 1){
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "该业主状态不为已迁入!");
            }
            // 3. 更新业主状态为2（已迁出）并设置迁出时间
            Map<String, Object> params = new HashMap<>();
            params.put("ownerId", ownerId);
            params.put("status", 2);
            boolean ownerResult = ownerMapper.updateOwnerStatus(params);
            if (!ownerResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "更新业主状态失败!");
            }
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            rabbitTemplate.convertAndSend("gxa.direct","deleteAAAA",CACHE_KEY_PREFIX_HOUSE+ownerId);
            return true;
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "业主迁出失败!"+e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean moveOutOwnerBatch(List<Long> houseIds) {
        try {
            if (houseIds == null || houseIds.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "房屋ID列表不能为空!");
            }
            
            // 1. 批量获取房屋对应的业主ID列表
            List<Long> ownerIds = new ArrayList<>();
            for (Long houseId : houseIds) {
                Long ownerId = ownerMapper.getOwnerIdByHouseId(houseId);
                if (ownerId != null) {
                    ownerIds.add(ownerId);
                }
            }
            // 1. 查询业主当前状态
            List<Integer> currentStatuses = ownerMapper.getOwnerStatusByIds(ownerIds);
            if (currentStatuses.size() != ownerIds.size()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "部分业主不存在!");
            }
            // 2. 验证所有业主状态都为1（已迁入状态）
            for (int i = 0; i < currentStatuses.size(); i++) {
                Integer currentStatus = currentStatuses.get(i);
                if (currentStatus == null || currentStatus != 1) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(),
                            "业主ID为 " + ownerIds.get(i) + " 的状态不是已迁入状态，无法进行迁出操作!");
                }
            }
            
            if (ownerIds.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "所选房屋都没有绑定业主!");
            }
            
            // 2. 批量更新房屋表，将业主ID设为NULL
            boolean houseResult = ownerMapper.moveOutOwnerBatch(houseIds);
            if (!houseResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量更新房屋信息失败!");
            }
            
            // 3. 批量更新业主状态为2（已迁出）并设置迁出时间
            boolean ownerResult = ownerMapper.updateOwnerStatusBatch(ownerIds, 2);
            if (!ownerResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量更新业主状态失败!");
            }
            // 发送缓存删除消息
            for (Long ownerId : ownerIds){
                rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                rabbitTemplate.convertAndSend("gxa.direct","deleteAAAA",CACHE_KEY_PREFIX_HOUSE+ownerId);
            }
            return true;
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量导出失败："+e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean moveInOwner(Long ownerId, Long houseId, Date moveInTime) {
        try {
            if (ownerId == null || houseId == null || moveInTime == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "参数不能为空!");
            }
            List<Long> ownerIds = new ArrayList<>();
            ownerIds.add(ownerId);
            List<Integer> currentStatuses = ownerMapper.getOwnerStatusByIds(ownerIds);
            Integer currentStatus = currentStatuses.get(0);
            if(currentStatus != 2 && currentStatus != 1){
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "该业主状态不为已迁出或已迁入!");
            }
            // 获取当前租户ID
            Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));
            
            // 检查业主是否存在且属于当前租户
            Owner owner = getById(ownerId);
            if (owner == null || !owner.getTenantId().equals(tenantId)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主不存在或无权限操作!");
            }
            
            // 检查房屋是否存在且属于当前租户
            QueryWrapper houseQueryWrapper = QueryWrapper.create().from(SpHouse.class);
            houseQueryWrapper.eq(SpHouse::getId, houseId)
                           .eq(SpHouse::getTenantId, tenantId);
            SpHouse house = spHouseService.getMapper().selectOneByQuery(houseQueryWrapper);
            if (house == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "房屋不存在或无权限操作!");
            }
            
            // 检查房屋是否已有业主
            if (house.getOwnerId() != null) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "该房屋已有业主，请先迁出!");
            }
            
            // 执行迁入操作
            // 1. 更新房屋的业主ID
            boolean houseResult = ownerMapper.updateHouseOwnerId(ownerId, houseId);
            if (!houseResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "更新房屋业主ID失败!");
            }
            
            // 2. 更新业主状态和迁入时间
            boolean ownerResult = ownerMapper.updateOwnerMoveInStatus(ownerId, moveInTime);
            if (!ownerResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "更新业主状态失败!");
            }
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            rabbitTemplate.convertAndSend("gxa.direct","deleteAAAA",CACHE_KEY_PREFIX_HOUSE+ownerId);
            return true;
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "业主迁入失败："+e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditOwnerBatch(List<Long> ownerIds, Integer status) {
        try {
            if (ownerIds == null || ownerIds.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主ID列表不能为空!");
            }

            // 1. 查询业主当前状态
            List<Integer> currentStatuses = ownerMapper.getOwnerStatusByIds(ownerIds);
            if (currentStatuses.size() != ownerIds.size()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "部分业主不存在!");
            }

            // 2. 验证所有业主状态都为0（待审核状态）
            for (int i = 0; i < currentStatuses.size(); i++) {
                Integer currentStatus = currentStatuses.get(i);
                if (currentStatus == null || currentStatus != 0) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(),
                            "业主ID为 " + ownerIds.get(i) + " 的状态不是待审核状态，无法进行审核操作!");
                }
            }
            if(status== 3){
                List<Long> houseIds = new ArrayList<>();
                for (Long ownerId : ownerIds) {
                    Long houseId = spHouseMapper.getHouseIdByOwnerID(ownerId);
                    houseIds.add(houseId);
                }
                //批量更新房屋表，将业主ID设为NULL
                boolean houseResult = ownerMapper.moveOutOwnerBatch(houseIds);

                if (!houseResult) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量更新房屋信息失败!");
                }
            }
            // 3. 批量更新业主状态和时间
            boolean ownerResult = ownerMapper.updateOwnerStatusAndTimeBatch(ownerIds, status);
            if (!ownerResult) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "更新操作失败，请联系管理员!");
            }

            return true;
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量审核业主失败："+e.getMessage());
        }
    }

    @Override
    public OwnerDetailVo getOwnerDetailById(Long ownerId) {
        try {
            if (ownerId == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主ID不能为空!");
            }

            // 获取当前租户ID
            Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));

            // 使用MyBatis-Flex自带的getById方法查询业主信息
            Owner owner = getById(ownerId);
            if (owner == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主不存在!");
            }

            // 验证租户权限
            if (!owner.getTenantId().equals(tenantId)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "无权限查看该业主信息!");
            }

            // 将Owner实体映射到OwnerDetailVo
            OwnerDetailVo ownerDetailVo = new OwnerDetailVo();
            ownerDetailVo.setCellId(owner.getCellId());
            ownerDetailVo.setName(owner.getName());
            ownerDetailVo.setPhone(owner.getPhone());
            ownerDetailVo.setGender(owner.getGender());
            ownerDetailVo.setEmail(owner.getEmail());
            ownerDetailVo.setStatus(owner.getStatus());
            ownerDetailVo.setRemark(owner.getRemark());
            ownerDetailVo.setIdCard(owner.getIdCard());
            ownerDetailVo.setMoveInTime(owner.getMoveInTime());
            ownerDetailVo.setResidentType(owner.getResidentType());

            return ownerDetailVo;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "获取业主详情失败!");
        }
    }

    @Override
    public String importOwners(java.io.InputStream inputStream) {
        try {
            // 获取当前租户ID
            Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));
            
            // 使用EasyExcel读取文件
            EasyExcel.read(inputStream, OwnerData.class,
                    new OwnerDataReadListener(this, ownerMapper, spHouseService,spHouseMapper,tenantId))
                    .sheet()
                    .doRead();
            
            return "导入成功";
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "导入业主信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteOwner(Long ownerId) {
        try {
            if (ownerId == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主ID不能为空!");
            }

            // 获取当前租户ID
            Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));

            // 检查业主是否存在且属于当前租户
            Owner owner = getById(ownerId);
            if (owner == null || !owner.getTenantId().equals(tenantId)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主不存在或无权限操作!");
            }

            // 检查业主状态，只有已迁出(status=2)和审核不通过(status=3)才能删除
            if (owner.getStatus() == null || (owner.getStatus() != 2 && owner.getStatus() != 3)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), 
                    "只有已迁出和审核不通过的业主才能删除!");
            }

//            List<Long> houseIds = new ArrayList<>();
//            Long houseId = spHouseMapper.getHouseIdByOwnerID(ownerId);
//            houseIds.add(houseId);
//            //批量更新房屋表，将业主ID设为NULL
//            boolean houseResult = ownerMapper.moveOutOwnerBatch(houseIds);
//            if (!houseResult) {
//                throw new BusinessException(ErrorCode.UPDATE_ERROR.getCode(), "更新房屋信息失败!");
//            }
            // 执行删除操作
            boolean result = removeById(ownerId);
            if (!result) {
                throw new BusinessException(ErrorCode.DELETE_ERROR.getCode(), "删除业主操作失败!");
            }
            return true;
        } catch (BusinessException e) {
            throw new BusinessException(ErrorCode.DELETE_ERROR.getCode(), "删除业主失败:"+e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteOwnerBatch(List<Long> ownerIds) {
        try {
            if (ownerIds == null || ownerIds.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主ID列表不能为空!");
            }

            // 获取当前租户ID
            Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));

            // 查询业主状态
            List<Integer> currentStatuses = ownerMapper.getOwnerStatusByIds(ownerIds);
            if (currentStatuses.size() != ownerIds.size()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "部分业主不存在!");
            }

            // 验证所有业主状态都为已迁出(status=2)或审核不通过(status=3)
            for (int i = 0; i < currentStatuses.size(); i++) {
                Integer currentStatus = currentStatuses.get(i);
                if (currentStatus == null || (currentStatus != 2 && currentStatus != 3)) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(),
                        "业主ID为 " + ownerIds.get(i) + " 的状态不是已迁出或审核不通过，无法删除!");
                }
            }

            // 验证租户权限
            for (Long ownerId : ownerIds) {
                Owner owner = getById(ownerId);
                if (owner == null || !owner.getTenantId().equals(tenantId)) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), 
                        "业主ID为 " + ownerId + " 不存在或无权限操作!");
                }
            }
//            List<Long> houseIds = new ArrayList<>();
//            for (Long ownerId : ownerIds) {
//                Long houseId = spHouseMapper.getHouseIdByOwnerID(ownerId);
//                houseIds.add(houseId);
//            }
//            //批量更新房屋表，将业主ID设为NULL
//            boolean houseResult = ownerMapper.moveOutOwnerBatch(houseIds);
//            if (!houseResult) {
//                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量更新房屋信息失败!");
//            }

            // 执行批量删除操作
            boolean result = removeByIds(ownerIds);
            if (!result) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量删除业主失败!");
            }


            return true;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "批量删除业主失败!");
        }
    }

    @Override
    public List<OwnerSearchVo> getOwnerIdsByName(String ownerName) {
        try {
            if (ownerName == null || ownerName.trim().isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "业主名字不能为空!");
            }

            // 获取当前租户ID
            Long tenantId = Convert.toLong(StpUtil.getExtra("tenant_id"));

            // 调用Mapper方法查询业主ID列表
            return ownerMapper.getOwnerIdsByName(ownerName.trim(), tenantId);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), "查询业主ID失败!");
        }
    }
}
